package validate

import (
	"errors"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"gopkg.in/go-playground/validator.v9"
	zh_translations "gopkg.in/go-playground/validator.v9/translations/zh"
	"reflect"
	"regexp"
)

const (
	vehicleNumberString = "^([京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新][ABCDEFGHJKLMNPQRSTUVWXY][1-9DF][1-9ABCDEFGHJKLMNPQRSTUVWXYZ]\\d{3}[1-9DF]|[京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新][ABCDEFGHJKLMNPQRSTUVWXY][\\dABCDEFGHJKLNMxPQRSTUVWXYZ]{5})$"
	userNameString      = "^[\u4E00-\u9FA5]{2,10}$"
	userPhoneString     = "^1[3456789]\\d{9}$"
)

var (
	vehicleNumber = regexp.MustCompile(vehicleNumberString)
	userName      = regexp.MustCompile(userNameString)
	userPhone     = regexp.MustCompile(userPhoneString)
)

func Validate(s interface{}) error {
	zh_ch := zh.New()
	newValidate := validator.New()
	uni := ut.New(zh_ch)
	trans, _ := uni.GetTranslator("zh")

	// 自定义的结构体对应名称，以 label 为标签
	newValidate.RegisterTagNameFunc(func(field reflect.StructField) string {
		label := field.Tag.Get("label")
		if label == "" {
			return field.Name
		}
		return label
	})

	// @@TODO 自定义函数的验证还没有加入中文翻译器
	// 增加自定义的验证函数
	newValidate.RegisterValidation("isVehicleNumber", isVehicleNumber)
	newValidate.RegisterValidation("isUserName", isUserName)
	newValidate.RegisterValidation("isUserPhone", isUserPhone)

	zh_translations.RegisterDefaultTranslations(newValidate, trans)
	err := newValidate.Struct(s)
	if err != nil {
		for _, err := range err.(validator.ValidationErrors) {
			return errors.New(err.Translate(trans))
		}

	}
	return err
}

// 自定义验证函数：车牌号验证
func isVehicleNumber(fl validator.FieldLevel) bool {
	return vehicleNumber.MatchString(fl.Field().String())
}

// 自定义验证函数：姓名验证
func isUserName(fl validator.FieldLevel) bool {
	return userName.MatchString(fl.Field().String())
}

// 自定义验证函数：手机号验证
func isUserPhone(fl validator.FieldLevel) bool {
	return userPhone.MatchString(fl.Field().String())
}
